<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no" />
  <meta name="theme-color" content="#000000" />
  <link rel="stylesheet" href="../../node_modules/bootstrap-css-only/css/bootstrap.min.css" />
  <!-- <link rel="manifest" href="./manifest.json" /> -->
  <title>autoEdit 3 - Settings</title>
  <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script> -->
  <script src="./babel.min.js"></script>
</head>

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
  <script type="text/babel">
    import React from "react";
    import ReactDOM from "react-dom";
    import Container from "react-bootstrap/Container";
    import Breadcrumb from "react-bootstrap/Breadcrumb";
    import Nav from "react-bootstrap/Nav";
    import Tabs from "react-bootstrap/Tabs";
    import Tab from "react-bootstrap/Tab";
    import Button from "react-bootstrap/Button";
    import ProgressBar from "react-bootstrap/ProgressBar";
    import Form from "react-bootstrap/Form";
    import Alert from "react-bootstrap/Alert";
    import { getDefaultStt, setDefaultStt } from "./default-stt.js";
    import speechmaticsLanguages from "./language-options/speechmatics.json";
    import assemblyAiLanguages from "./language-options/assemblyai.json";
    import {
      getCredentials,
      setCredentials,
      getIsDeepspeechModelSet,
      setDeepSpeechModel,
      getDeepSpeechModelPath
    } from "./credentials.js";
    const { ipcRenderer } = require('electron');
    const appVersion = ipcRenderer.sendSync('synchronous-message-get-app-version', 'ping');


    class CustomAlert extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          show: true
        };
      }

      handleDismiss = () => this.setState({ show: false });

      render() {
        if (this.state.show) {
          return (
            <Alert
              variant={this.props.variant}
              onClose={this.handleDismiss}
            // dismissible
            >
              {this.props.heading ? (
                <Alert.Heading>{this.props.heading}</Alert.Heading>
              ) : (
                ""
              )}
              {this.props.message}
            </Alert>
          );
        } else {
          return (
            <React.Fragment>
              <br />
            </React.Fragment>
          );
        }
      }
    }

    class SelectDefaultStt extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          defaultStt: "",
          language: null,
          languageModel: null,
          deepspeechDownloadProgress: 0
        };
      }

      componentDidMount() {
        const { provider, language, languageModel } = getDefaultStt();
        // console.log("provider, language", provider, language);
        const isDeepspeechModelSet = getIsDeepspeechModelSet();
        this.setState({
          defaultStt: provider,
          language: language,
          isDeepspeechModelSet: isDeepspeechModelSet,
          languageModel: languageModel,
          downloadingDeepspeech: false
        });
      }
      handleChangeDefaultStt = e => {
        console.log(e, e.target.value);
        const tmpDefaultStt = e.target.value;
        let tmpLangueModel = this.state.languageModel;
        let tmpLanguage = this.state.language;

        if ((tmpDefaultStt === 'AssemblyAI') && (!tmpLangueModel || !tmpLangueModel.includes('assemblyai_'))) {
          tmpLangueModel = 'assemblyai_default';
        }

        if ((tmpDefaultStt === 'AssemblyAI') && (!tmpLanguage || !tmpLanguage.includes('assemblyai_'))) {
          tmpLanguage = 'assemblyai_default'
        }
        else if (tmpDefaultStt === 'Speechmatics') {
          tmpLanguage = 'en';
          tmpLangueModel = null;
        } else if (tmpDefaultStt === 'pocketsphinx') {
          tmpLanguage = null;
          tmpLangueModel = null;
        } else if (tmpDefaultStt === 'deepspeech') {
          tmpLanguage = null;
          tmpLangueModel = null;
        }

        this.setState((prevState, props) => {
          console.log('tmpLangueModel', tmpLangueModel, 'tmpLanguage', tmpLanguage, 'tmpDefaultStt', tmpDefaultStt)
          return {
            defaultStt: tmpDefaultStt,
            languageModel: tmpLangueModel,
            language: tmpLanguage,
            saved: false
          }
        });
      };

      handleChangeLanguage = e => {
        this.setState({
          language: e.target.value,
          saved: false
        });
      };

      handleChangeDefautLanguageModel = e => {
        this.setState({
          languageModel: e.target.value,
          saved: false
        });
      };

      handleSave = () => {

        setDefaultStt({
          language: this.state.language,
          provider: this.state.defaultStt,
          languageModel: this.state.languageModel
        });
        this.setState({
          saved: true
        });
      };

      progressCallback = (progressData) => {
        this.setState({
          deepspeechDownloadProgress: progressData
        })
      }

      handleDownloadDeepspeechModel = async () => {
        console.log("handleDownloadDeepspeechModel");
        this.setState({
          downloadingDeepspeech: true
        });
        setDeepSpeechModel(this.progressCallback).then(res => {
          this.setState({
            isDeepspeechModelSet: true,
            downloadingDeepspeech: false
          });
        });
      };

      render() {
        let languagesOptions = [
          <option value="" key="default" disabled></option>
        ];
        if (
          this.state.defaultStt === "AssemblyAI" &&
          this.state.defaultStt === "pocketsphinx" &&
          this.state.defaultStt === "deepspeech"
        ) {
          languagesOptions = [
            <option value="en" key="en" disabled>
              English
              </option>
          ];
        }
        if (this.state.defaultStt === "Speechmatics") {
          languagesOptions = speechmaticsLanguages.map((language, index) => {
            return (
              <option key={language.code} value={language.code}>
                {language.language}
              </option>
            );
          });
        }
        else if (this.state.defaultStt === "AssemblyAI") {
          languagesOptions = assemblyAiLanguages.map((language, index) => {
            return (
              <option key={language.code} value={language.code}>
                {language.language}
              </option>
            );
          });
        }


        let languageToDisplay = "English";
        console.log("this.state.provider ", this.state.defaultStt);
        if (this.state.defaultStt === "Speechmatics") {
          console.log("here!");
          languageToDisplay = speechmaticsLanguages.find(language => {
            return language.code === this.state.language;
          });
          console.log("languageToDisplay", languageToDisplay);
          if (languageToDisplay) {
            languageToDisplay = languageToDisplay.language;
          }
        } else if (this.state.defaultStt === "AssemblyAI") {
          console.log("here!");
          languageToDisplay = assemblyAiLanguages.find(language => {
            return language.code === this.state.language;
          });
          if (languageToDisplay) {
            languageToDisplay = languageToDisplay.language;
          }
        }

        return (
          <div>
            <br />
            {this.state.saved ? (
              <Container>
                <CustomAlert
                  variant={"success"}
                  heading={"Saved"}
                  message={
                    <p>
                      Saved <b>{this.state.defaultStt}</b> and{" "}
                      <b>{languageToDisplay}</b> as defaults!
                      </p>
                  }
                />
              </Container>
            ) : null}

            <h3>Default STT</h3>
            <br />
            <Form.Group controlId="exampleForm.ControlSelect1">
              <Form.Label>Default Speech To Text engine</Form.Label>
              <Form.Control
                as="select"
                value={this.state.defaultStt}
                onChange={this.handleChangeDefaultStt}
              >
                <option value="AssemblyAI">AssemblyAI</option>
                {/*<option value="Speechmatics">Speechmatics</option>*/}
                {/* TODO: M1 - Apple M1 disabling deepspeech until can figure out how to make module compatible -*/}
                {process.platform==="darwin" && process.arch !=='arm64' &&(
                <option value="deepspeech">
                  Mozilla Deepspeech (offline){" "}
                </option>)}
                {process.platform === "darwin" && (
                  <option value="pocketsphinx">Pocketsphinx (offline)</option>
                ) }
                <option value="" disabled></option>
              </Form.Control>
              <Form.Text className="text-muted">
                Choose the default STT you would like to use for your
                transcriptions
                </Form.Text>
            </Form.Group>

            {
              // this.state.defaultStt !== "AssemblyAI" &&
              this.state.defaultStt !== "pocketsphinx" &&
                this.state.defaultStt !== "deepspeech" ? (
                <Form.Group controlId="exampleForm.ControlSelect1">
                  <Form.Label>Default Speech To Text language</Form.Label>
                  <Form.Control
                    as="select"
                    value={this.state.language}
                    onChange={this.handleChangeLanguage}
                  >
                    {languagesOptions}
                  </Form.Control>
                  <Form.Text className="text-muted">
                    Choose the default STT language you would like to use for
                    your transcriptions
                  </Form.Text>
                </Form.Group>
              ) : (
                <React.Fragment>
                  <Form.Label>Default Speech To Text language</Form.Label>
                  <Form.Text className="text-muted">
                    Only English available as default{" "}
                  </Form.Text>

                  {this.state.defaultStt === "deepspeech" && !this.state.downloadingDeepspeech ? (
                    this.state.isDeepspeechModelSet ? (
                      <Form.Text className="text-info">
                        You have downloaded the Deepspeech STT model (1.8gb) and
                        are ready to go
                      </Form.Text>
                    ) : (
                      <React.Fragment>
                        <br />
                        <CustomAlert
                          variant={"info"}
                          message={
                            <React.Fragment>
                              <p>
                                You need to download the Mozilla Deepspeech STT
                                Model (1.8gb) to be able to use this STT Engine
                                (offline)
                              </p>
                              <Button
                                variant="outline-info"
                                block
                                onClick={this.handleDownloadDeepspeechModel}
                              >
                                Download
                              </Button>
                            </React.Fragment>
                          }
                        />
                      </React.Fragment>
                    )
                  ) : null}

                  {this.state.downloadingDeepspeech ? (
                    <React.Fragment>
                      <h6>Downloading Deepspeech model</h6>
                      <ProgressBar animated now={this.state.deepspeechDownloadProgress} label={`${parseInt(this.state.deepspeechDownloadProgress)}%`} />
                    </React.Fragment>
                  ) : null}
                </React.Fragment>
              )}


            {this.state.defaultStt === "AssemblyAI" &&
              <React.Fragment>

                <Form.Group controlId="exampleForm.ControlSelect1">
                  <Form.Label>Default Language model</Form.Label>
                  <Form.Control
                    as="select"
                    value={this.state.languageModel}
                    onChange={this.handleChangeDefautLanguageModel}
                  >
                    <option value="assemblyai_default">Default</option>
                    <option value="assemblyai_media">Media</option>
                  </Form.Control>
                  <Form.Text className="text-muted">
                    Choose the default language model to boost accuracy. <br />
                    <code>default</code> is best for conversational data like phone calls and meetings.<br />
                    <code>assemblyai_media</code> is best for broadcast news and radio and at recognizing proper nouns, this model has a much larger vocabulary than the default model.
                </Form.Text>
                </Form.Group>
              </React.Fragment>
            }
            <Button onClick={this.handleSave} variant="outline-primary" block>
              Save default configuration
              </Button>
          </div>
        );
      }
    }

    class SettingsForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          sttUserName: this.props.sttUserName,
          sttAPIKey: this.props.sttAPIKey,
          sttAPIUrl: this.props.sttAPIUrl
        };
      }

      handlesttUserNameChange = event => {
        this.setState({ sttUserName: event.target.value });
      };
      handleSTTAPIKeyChange = event => {
        this.setState({ sttAPIKey: event.target.value });
      };

      handleSTTAPIUrlChange = event => {
        this.setState({ sttAPIUrl: event.target.value });
      };

      handleSubmit(event) {
        const form = event.currentTarget;
        if (!form.checkValidity()) {
          event.preventDefault();
          event.stopPropagation();
          this.setState({ validated: true });
        }

        if (form.checkValidity()) {
          event.preventDefault();
          event.stopPropagation();
          const tmpItem = {
            provider: this.props.provider,
            sttUserName: this.state.sttUserName,
            sttAPIKey: this.state.sttAPIKey,
            sttAPIUrl: this.state.sttAPIUrl
          };
          this.props.handleSave(tmpItem);
        }
        //this.setState({ redirect: true, newProjectId: response.projectId });
      }
      render() {
        console.log(
          "SettingsForm-this.state.sttUserName",
          this.state.sttUserName
        );
        return (
          <div>
            <h4> {this.props.provider} service credentials</h4>
            <Form
              noValidate
              validated={this.state.validated}
              onSubmit={e => this.handleSubmit(e)}
            >
              <Form.Text className="text-muted">
                {this.props.customInstructions}
              </Form.Text>

              {this.state.sttUserName !== false ? (
                <Form.Group controlId="sttUserName">
                  <Form.Label>STT user name</Form.Label>
                  <Form.Control
                    type="text"
                    placeholder="Enter the STT user name"
                    value={this.state.sttUserName}
                    // defaultValue={ this.state.sttAPIKey }
                    onChange={this.handlesttUserNameChange}
                    required
                  />
                  <Form.Text className="text-muted">
                    STT user name provided by {this.props.provider}
                  </Form.Text>
                  <Form.Control.Feedback>Looks good!</Form.Control.Feedback>
                  <Form.Control.Feedback type="invalid">
                    Please add the Speech To STT user name
                    </Form.Control.Feedback>
                </Form.Group>
              ) : null}

              {this.state.sttAPIKey !== false ? (
                <Form.Group controlId="sttAPIKey">
                  <Form.Label>API Key</Form.Label>
                  <Form.Control
                    type="text"
                    placeholder="Enter the API Key"
                    value={this.state.sttAPIKey}
                    // defaultValue={ this.state.sttAPIKey }
                    onChange={this.handleSTTAPIKeyChange}
                    required
                  />
                  <Form.Text className="text-muted">
                    API Key provided by {this.props.provider}
                  </Form.Text>
                  <Form.Control.Feedback>Looks good!</Form.Control.Feedback>
                  <Form.Control.Feedback type="invalid">
                    Please add the Speech To Text API Key
                    </Form.Control.Feedback>
                </Form.Group>
              ) : null}

              {this.state.sttAPIUrl !== false ? (
                <Form.Group controlId="sttAPIUrl">
                  <Form.Label>API URL</Form.Label>
                  <Form.Control
                    type="text"
                    placeholder="Enter the STT API URL"
                    value={this.state.sttAPIUrl}
                    // defaultValue={ this.state.sttAPIUrl }
                    onChange={this.handleSTTAPIUrlChange}
                    required
                  />
                  <Form.Text className="text-muted">
                    API Key provided by {this.props.provider}
                  </Form.Text>
                  <Form.Control.Feedback>Looks good!</Form.Control.Feedback>
                  <Form.Control.Feedback type="invalid">
                    Please add the Speech To Text API Key
                    </Form.Control.Feedback>
                </Form.Group>
              ) : null}

              {/* on change save - send to server as post + link to projects list? */}
              <Button variant="outline-primary" type="submit" block>
                Save {this.props.provider} credentials
                </Button>
            </Form>
          </div>
        );
      }
    }

    class Settings extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          saved: false,
          speechmaticsSTTUsername: false,
          speechmaticsApiKey: false,
          assemblyAISttAPIKey: false,
          isDeepspeechModelSet: false,
          currentSavedProvider: ""
        };
      }

      componentDidMount = () => {
        const speechmaticsCredentials = getCredentials("Speechmatics");
        // console.log('speechmaticsCredentials', speechmaticsCredentials);
        const assemblyAiCred = getCredentials("AssemblyAI");
        // console.log('AssemblyAICredentials',AssemblyAICredentials)
        const isDeepspeechModelSet = getIsDeepspeechModelSet();
        this.setState(
          {
            speechmaticsSTTUsername: speechmaticsCredentials.sttUserName,
            speechmaticsApiKey: speechmaticsCredentials.sttAPIKey,
            assemblyAISttAPIKey: assemblyAiCred.sttAPIKey,
            isDeepspeechModelSet: isDeepspeechModelSet
          },
          () => {
            this.forceUpdate();
          }
        );
      };

      handleSave = data => {
        setCredentials(data);
        // Todo consider adding some error handling
        this.setState({
          saved: true,
          currentSavedProvider: data.provider
        });
      };

      render() {
        return (
          <Container>
            <br />
            <Breadcrumb>
              <Breadcrumb.Item active>
                Settings - v{appVersion}
              </Breadcrumb.Item>
            </Breadcrumb>
            <Tabs defaultActiveKey={"defaultStt"}>
              <Tab eventKey="defaultStt" title="Default STT">
                <SelectDefaultStt />
              </Tab>
              <Tab eventKey="settings" title="Settings">
                <br />
                {this.state.saved ? (
                  <CustomAlert
                    variant={"success"}
                    heading={"Saved"}
                    message={
                      <p>
                        Saved <b>{this.state.currentSavedProvider}</b>{" "}
                          credentials!
                        </p>
                    }
                  />
                ) : null}

                <h3>STT Settings</h3>
                <br />
                <Tabs defaultActiveKey="assemblyai">
                  {this.state.assemblyAISttAPIKey !== false ? (
                    <Tab eventKey="assemblyai" title="AssemblyAI">
                      <SettingsForm
                        sttUserName={false}
                        sttAPIKey={this.state.assemblyAISttAPIKey}
                        sttAPIUrl={false}
                        provider={"AssemblyAI"}
                        handleSave={this.handleSave}
                      />
                    </Tab>
                  ) : null}
                  {/*commenting out speechmatics, while waiting for a more substantial refactor to remove it or replace it with IMB Watson */}
                  {false && this.state.speechmaticsSTTUsername !== false &&
                    this.state.speechmaticsApiKey !== false ? (
                    <Tab eventKey="speechmatics" title="Speechmatics">
                      <SettingsForm
                        sttUserName={this.state.speechmaticsSTTUsername}
                        sttAPIKey={this.state.speechmaticsApiKey}
                        sttAPIUrl={false}
                        provider={"Speechmatics"}
                        handleSave={this.handleSave}
                      />
                    </Tab>
                  ) : null}
                </Tabs>
              </Tab>
            </Tabs>
          </Container>
        );
      }
    }
    ReactDOM.render(<Settings />, document.getElementById("root"));
  </script>
</body>

</html>